[AD] Scalaアプリケーションの開発・保守は合同会社ミルクソフトにお任せください
この記事では、Scala 3(Dotty)で導入された「クリエイターアプリケーション」という機能について解説します。
new
キーワード無しにクラスをインスタンス化できる機能「クリエイターアプリケーション」
Scala 3では、単純な関数の呼び出し構文を使用して、クラスをインスタンス化することができます。
class File(s: String) { def this() = this("") } File("abc") // same as new File("abc") File() // same as new File()
この機能は「クリエイターアプリケーション機能」と呼ばれています。
new
を省略することで実装の詳細を隠すことができ、コードがより読みやすくなります。
case class
には既にあるこの機能はよく活用されており、実情として、case class
を「new
を書かなくてよくする」ためだけに定義する例が多く見受けられるほどでした。
今回、これまでcase class
に対してのみ提供されてきた「new
を省略する」という機能を一般のクラスにも追加しました。
わざわざcase class
を使わなくてもnew
を書かなくてよくなったというのがポイントです。
「クリエイターアプリケーション」という新しい規則が生まれてしまったものの、case class
と同じ機能が普通のクラスにも備えられたことにより、覚える側としてはシンプルになりました。
クリエイターアプリケーションの仕組みはcase classとは異なる
さて、ここから先は細かい話になります。
普通のクラスとcase class
とでは、new
キーワードなしに新しいインスタンスを生成できるという挙動は同じように見えます。
しかし、これを実現する仕組みはそれぞれ異なります。
case class
では、コンパイラが自動的にapply
メソッドを生成しています。
普通のクラスにおいては、コンパイラは関数呼び出し f(args)
に対して新しい解釈をするようになりました。
これまでは、関数呼び出し f(args)
が与えられた場合、以下の3つの規則を順次適用していました。
f
がargs
に適用可能なメソッドである場合、そのままf(args)
として解釈する- そうでなければ、
f
がargs
に適用可能なapply
メソッドをメンバとして持っている場合は、f.apply(args)
として解釈する - そうでなければ、
f
がp.m
の形式で、p
に適用可能な暗黙の変換c
があり、c(p).m
がargs
に適用可能である場合は、c(p).m(args)
として解釈する
クリエイターアプリケーション機能の実現のため、これらの規則に続く第4の規則が作られました。
- そうでなければ、
f
が構文的に安定した識別子であり、f
を型識別子として解釈した場合のnew f
がargs
に適用可能な場合、新しいf(args)
として解釈する
同様に、型引数f[targs]
を持つ関数呼び出しの可能な解釈は、最終的なフォールバックとして以下の解釈で拡張されます。
f
が構文的に安定した識別子であり、型識別子として解釈した場合のnew f[targs]
が実際に型付けられていれば、new f[targs]
として解釈する